A hello-world style introduction to Interactive JavaScript in a Notebook, along with using node.js, and node modules.
In [1]:
var util = require('util')
var greeting = util.format('Hello %s!', 'Nikhil Kothari');
console.log(greeting);
Node.js modules can be installed via the %module
command. Modules are installed using npm
along with their dependencies, so that they can subsequently loaded using require()
.
In [2]:
%module qr-image
In [3]:
var qr = require('qr-image');
function qrCode(text) {
var buffer = qr.imageSync(text, { type: 'png' });
return _.data.image(buffer);
}
qrCode(greeting);
Within a notebook, the expectation is that a cell completes execution before the next cell begins to execute. As a result, some special treatment is required to indicate when async APIs, which are quite prevalent in node.js, have completed.
Async APIs in node.js take an async completion callback. The callback pattern can be converted to a promise, and have the resulting promise be treated as the result of the cell execution, that the notebook waits on to know when the cell has completed execution.
Creating and returning a promise is simplified in notebooks via the helper _.async()
method as shown below. This helper method accepts a function that is passed in a deferred result. This deferred result can be resolved or rejected when the async work completes successfully or with a failure.
In [4]:
_.async(function(deferred) {
var buffers = [];
qr.image(greeting)
.on('end', function() {
var buffer = Buffer.concat(buffers);
deferred.resolve(_.data.image(buffer));
})
.on('data', function(chunk) {
buffers.push(chunk);
});
});